from django.contrib.auth.decorators import login_required
from django.db import transaction
from django.http import HttpRequest, HttpResponse, JsonResponse, HttpResponseBadRequest
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib import messages

from main.models import *
from django.core.paginator import Paginator
from .forms import *


# Create your views here.
@login_required
def index(request):
    """仪表板 - 显示当前用户的主号码信息"""
    context = {}
    try:
        # 获取用户的主号码
        primary_phone = Phone.objects.filter(
            user=request.user,
            is_primary=True
        ).first()

        if not primary_phone:
            # 如果没有主号码，获取第一个号码
            primary_phone = Phone.objects.filter(user=request.user).first()
        context = {
            'primary_phone': primary_phone,
        }

        if primary_phone:
            # 获取余额信息
            try:
                balance = primary_phone.balance
            except Balance.DoesNotExist:
                balance = Balance.objects.create(phone=primary_phone)

            # 获取套餐信息
            phone_combo = (
                PhoneCombo.objects
                .filter(phone=primary_phone, is_active=True)
                .order_by('-start_time')
                .first()
            )

            # 若存在套餐，根据套餐刷新剩余用量（首次或为0时）
            if phone_combo and (
                    balance.data_remaining == 0 and balance.voice_remaining == 0 and balance.sms_remaining == 0
            ):
                balance.update_allowance()

            # 缴费记录与使用记录（分页）
            payments_qs = (
                Payment.objects
                .filter(phone=primary_phone)
                .order_by('-payment_time')
            )
            usage_qs = (
                UsageRecord.objects
                .filter(phone=primary_phone)
                .order_by('-usage_time')
            )

            per_page = 10
            payment_page_num = request.GET.get('payment_page') or 1
            record_page_num = request.GET.get('record_page') or 1

            payments_page = Paginator(payments_qs, per_page).get_page(payment_page_num)
            usage_page = Paginator(usage_qs, per_page).get_page(record_page_num)

            context.update({
                'balance': balance,
                'phone_combo': phone_combo,
                'recent_payments': payments_page,  # 保持变量名，改为分页对象
                'recent_use_recode': usage_page     # 保持变量名，改为分页对象
            })

        return render(request, 'main/index.html', context)

    except Exception as e:
        messages.error(request, f'加载仪表板时出错: {str(e)}')
        return render(request, 'main/index.html', context)


@login_required
def phone_manage(request):
    if request.method == 'POST':
        action = request.POST.get('action')

        if action == 'add':
            form = PhoneForm(request.POST)
            if form.is_valid():
                phone: Phone = form.save(commit=False)
                phone.user = request.user
                phone.save()
                messages.success(request, '号码已添加')
            else:
                messages.error(request, '号码无效，请检查输入')

        elif action == 'set_primary':
            phone_id = request.POST.get('phone_id')
            phone = Phone.objects.filter(id=phone_id, user=request.user).first()
            if phone:
                phone.is_primary = True
                phone.save(update_fields=['is_primary'])
                messages.success(request, f'已切换为{phone.phonenumber}')
                return redirect('main:index')
            else:
                messages.error(request, '未找到该号码')

        elif action == 'delete':
            phone_id = request.POST.get('phone_id')
            deleted, _ = Phone.objects.filter(id=phone_id, user=request.user).delete()
            if deleted:
                messages.success(request, '号码已删除')
            else:
                messages.error(request, '未找到该号码')

        return redirect('main:phone_manage')

    # GET
    form = PhoneForm()
    phones = Phone.objects.filter(user=request.user).order_by('-is_primary', '-create_time')
    return render(request, 'main/phone_manage.html', {
        'form': form,
        'phones': phones,
    })


@login_required
def combo(request):
    combos = Combo.objects.all()

    return render(request, 'main/combo.html', context={'combos': combos})


@login_required
def combo_detail(request, pk):
    try:
        combo = get_object_or_404(Combo, id=pk)
    except:
        return HttpResponse("先选择套餐")
    if combo:
        return render(request, 'main/combo_detail.html', context={'combo': combo})
    else:
        return HttpResponse("先选择套餐")


@login_required
def add_money(request, pk):
    phone = get_object_or_404(Phone, id=pk, user=request.user)
    form = PaymentForm()
    if request.method == 'POST':
        form = PaymentForm(request.POST)
        if form.is_valid():
            with transaction.atomic():
                payment = form.save(commit=False)
                payment.phone = phone
                payment.save()
                messages.success(request, f'缴费成功！已为 {phone.phonenumber} 充值 ¥{payment.amount}')
                return redirect('main:index')
    return render(request, 'main/add_money.html', context={'pk': pk, 'phone': phone, 'form': form})


def combo_choice(request, pk):
    phone = get_object_or_404(Phone, id=pk, user=request.user)
    # 获取当前激活套餐（而不是反向管理器本身）
    current_combo = (
        PhoneCombo.objects
        .filter(phone=phone, is_active=True)
        .order_by('-start_time')
        .first()
    )
    combos = Combo.objects.filter(is_active=True)
    combo_form = ComboSelectionForm()
    if request.method == 'POST':
        combo_form = ComboSelectionForm(request.POST)
        if combo_form.is_valid():
            selected_combo = combo_form.cleaned_data['plan']

            # 更新或创建套餐关联
            phone_combo, created = PhoneCombo.objects.get_or_create(
                phone=phone,
                defaults={'combo': selected_combo, 'is_active': True}
            )

            if not created:
                phone_combo.combo = selected_combo
                phone_combo.is_active = True
                phone_combo.save()

            # 更新余额信息
            balance, _ = Balance.objects.get_or_create(phone=phone)
            balance.update_allowance()

            messages.success(request, f'成功为 {phone.phonenumber} 设置套餐: {selected_combo.name}')
            return redirect('main:combo_choice', pk=pk)

    context = {
        'phone': phone,
        'current_combo': current_combo,
        'combos': combos,
        'combo_form': combo_form,
    }

    return render(request, 'main/combo_choice.html', context)


@login_required
def simulate_use(request, action: str, phone_id: int, amount: int):
    """模拟使用：扣减余额中的对应用量并记录使用记录。

    路由：/simulate/<action>/<phone_id>/<amount>/
    - action ∈ {data, voice, sms}
    - 仅允许 POST
    - 仅允许操作当前登录用户名下的号码
    返回 JSON：{ ok, message, new }
    """
    if request.method != 'POST':
        return HttpResponseBadRequest('Unsupported method')

    action = (action or '').strip().lower()
    if action not in {'data', 'voice', 'sms'}:
        return JsonResponse({'ok': False, 'message': 'Unknown action'}, status=400)

    phone = Phone.objects.filter(id=phone_id, user=request.user).first()
    if not phone:
        return JsonResponse({'ok': False, 'message': '号码不存在或无权限'}, status=404)

    try:
        amount = int(amount)
    except Exception:
        return JsonResponse({'ok': False, 'message': 'amount 无效'}, status=400)
    if amount <= 0:
        return JsonResponse({'ok': False, 'message': 'amount 必须为正整数'}, status=400)

    with transaction.atomic():
        balance, _ = Balance.objects.select_for_update().get_or_create(phone=phone)

        # 选择字段
        if action == 'data':
            current = balance.data_remaining
            field_name = 'data_remaining'
        elif action == 'voice':
            current = balance.voice_remaining
            field_name = 'voice_remaining'
        else:
            current = balance.sms_remaining
            field_name = 'sms_remaining'

        if current < amount:
            return JsonResponse({'ok': False, 'message': '剩余额度不足'}, status=400)

        new_value = current - amount

        # 更新余额字段
        setattr(balance, field_name, new_value)
        balance.save(update_fields=[field_name, 'last_updated'])

        # 写入使用记录
        UsageRecord.objects.create(
            phone=phone,
            usage_type=action,
            amount_used=amount,
            description=f'模拟使用 {amount}'
        )

    # 返回最新余额
    return JsonResponse({
        'ok': True,
        'message': '操作成功',
        'new': {
            'data_remaining': balance.data_remaining,
            'voice_remaining': balance.voice_remaining,
            'sms_remaining': balance.sms_remaining,
        }
    })
